package com.dc.kylin.integration.lock;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Component
public class RedisDistributedLock {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    //锁前缀
    private static final String LOCK_KEY_PREFIX = "scheduled_task_lock:";
    //锁默认超时时间30s
    private static final int LOCK_EXPIRE_TIME = 30;

    /*****
     * 尝试获取锁
     * @param taskName   任务名称
     * @param nodeIdentifier  节点标识
     * @return
     */
    public Boolean tryAcquireLock(String taskName, String nodeIdentifier) {
        String lockKey = LOCK_KEY_PREFIX + taskName;
        //String lockValue = UUID.randomUUID().toString();
        String lockValue = String.valueOf(System.currentTimeMillis() + LOCK_EXPIRE_TIME * 1000);

        if(Boolean.TRUE.equals(redisTemplate.opsForValue().setIfAbsent(lockKey, lockValue,LOCK_EXPIRE_TIME, TimeUnit.SECONDS))) {
            return true;
        }else{
            String currentValue = (String) redisTemplate.opsForValue().get(lockKey);
            //判断从Redis中查询到的数据，若小于当前时间，
            if(currentValue != null && Long.parseLong(currentValue) < System.currentTimeMillis()) {
                String oldValue = (String) redisTemplate.opsForValue().getAndSet(lockKey, lockValue);
                if(null != oldValue && oldValue.equals(currentValue)) {
                    return true;
                }
            }
        }
        return false;
    }


    /*****
     * 释放锁
     * @param taskName
     * @param nodeIdentifier
     */
    public void releaseLock(String taskName, String nodeIdentifier) {
        String lockKey = LOCK_KEY_PREFIX + taskName;
        redisTemplate.delete(lockKey);
    }
}
